﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using DeVetma.admin.classes;
using DeVetma.admin.models.database.metadata;
using DeVetma.admin.models.database;
using DeVetma.admin.models.entities;

namespace DeVetma.admin.models.managers
{
    public class OrderDetailsManager : DataManager<OrderDetails>
    {
        public override bool add(OrderDetails entity)
        {
            bool res = base.add(entity);

            if (res)
            {
                entity.clothe.retrieveStock(entity.odQuantity);
                entity.commitQtyUpdate();
            }

            return res;
        }

        public override bool addAll(OrderDetails[] entities, List<OrderDetails> failed)
        {
            List<OrderDetails> failedList = new List<OrderDetails>();
            bool passedAll = base.addAll(entities, failedList);

            OrderDetails[] passed = entities.Except(failed.ToArray()).ensure().ToArray();
            foreach (var suc in passed)
            {
                suc.clothe.retrieveStock(suc.odQuantity);
                suc.commitQtyUpdate();
            }

            if (failed != null)
                failed.AddRange(failedList);

            return passedAll;
        }

        public override bool delete(OrderDetails entity)
        {
            bool res = base.delete(entity);

            if (res)
                entity.clothe.addStock(entity.odQuantity);

            return res;
        }

        public override bool deleteAll(OrderDetails[] entities, List<OrderDetails> failed)
        {
            List<OrderDetails> failedList = new List<OrderDetails>();
            bool passedAll = base.deleteAll(entities, failed);

            OrderDetails[] passed = entities.Except(failed.ToArray()).ensure().ToArray();
            foreach (var suc in passed)
                suc.clothe.addStock(suc.odQuantity);

            if (failed != null)
                failed.AddRange(failedList);

            return passedAll;
        }

        public override bool update(OrderDetails entity)
        {
            bool res = base.update(entity);

            if (res)
            {
                int old = entity.getODQuantityOld();

                if (entity.odQuantity > old)
                    entity.clothe.retrieveStock(entity.odQuantity - old);
                else if (entity.odQuantity < old)
                    entity.clothe.addStock(old - entity.odQuantity);

                entity.commitQtyUpdate();
            }

            return res;
        }

        public override bool updateAll(OrderDetails[] entities, List<OrderDetails> failed)
        {
            List<OrderDetails> failedList = new List<OrderDetails>();
            bool passedAll = base.updateAll(entities, failed);

            OrderDetails[] passed = entities.Except(failed.ToArray()).ensure().ToArray();
            foreach (var entity in passed)
            {
                int old = entity.getODQuantityOld();

                if (entity.odQuantity > old)
                    entity.clothe.retrieveStock(entity.odQuantity - old);
                else if (entity.odQuantity < old)
                    entity.clothe.addStock(old - entity.odQuantity);

                entity.commitQtyUpdate();
            }

            if (failed != null)
                failed.AddRange(failedList);

            return passedAll;
        }

        public override string ensureKey(OrderDetails entity)
        {
            List<OrderDetails> orderDetails = getAll();

            int len = (orderDetails.Count < 1 ? 1 : ((int)Math.Log10(orderDetails.Count)) + 2);
            entity.odID = Utilities.randomizeNumericString(len);
            while (orderDetails.Exists(q => q.odID == entity.odID))
                entity.odID = Utilities.randomizeNumericString(len);

            return entity.odID;
        }

        public List<OrderDetails> getByOrderId(string id)
        {
            return getAll().Where(q => q.oID == id).ensure();
        }

        public List<OrderDetails> getByClothesId(string id)
        {
            return getAll().Where(q => q.cID == id).ensure();
        }

        public OrderDetails getByOrderClothes(string oID, string cID)
        {
            return getByOrderId(oID).Where(q => q.cID == cID).FirstOrDefault();
        }
    }
}